﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text;

namespace Zhp.Common.Helper
{
    public static class HttpHelper
    {
        public static string GetControllerName(this HttpContext httpContext)
        {
            return httpContext.GetRouteValue("controller")?.ToString();
        }

        public static string GetActionName(this HttpContext httpContext)
        {
            return httpContext.GetRouteValue("action")?.ToString();
        }

        public static string GetIP(this HttpContext httpContext)
        {
            return httpContext.Connection.RemoteIpAddress?.ToString() ?? "0.0.0.0";
        }

        /// <summary>
        /// 获取所有请求的参数（包括get参数和post参数）
        /// </summary>
        /// <param name="context">请求上下文</param>
        /// <returns></returns>
        public static async Task<Dictionary<string, object>> GetAllRequestParams(this HttpContext context)
        {
            var request = context.Request;
            var allParams = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

            // 并行处理查询参数和表单参数
            var queryParamsTask = Task.Run(() => ProcessQueryParams(request, allParams));
            var formParamsTask = Task.Run(() => ProcessFormParams(request, allParams));

            // 处理JSON body（如果需要）
            if (IsJsonContentType(request.ContentType))
            {
                await ProcessJsonBody(request, allParams);
            }

            await Task.WhenAll(queryParamsTask, formParamsTask);
            return allParams;
        }

        private static void ProcessQueryParams(HttpRequest request, Dictionary<string, object> allParams)
        {
            foreach (var param in request.Query)
            {
                allParams[param.Key] = IsPasswordField(param.Key) ? "********" : param.Value.ToString();
            }
        }

        private static void ProcessFormParams(HttpRequest request, Dictionary<string, object> allParams)
        {
            if (request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            try
            {
                foreach (var param in request.Form)
                {
                    allParams[param.Key] = IsPasswordField(param.Key) ? "********" : param.Value.ToString();
                }
            }
            catch
            {
                // 忽略表单处理异常
            }
        }

        private static async Task ProcessJsonBody(HttpRequest request, Dictionary<string, object> allParams)
        {
            if (request.Body == null || !request.Body.CanRead)
            {
                return;
            }

            try
            {
                request.Body.Position = 0; // 重置流位置以便读取
                using var reader = new StreamReader(request.Body, Encoding.UTF8, leaveOpen: true);

                string jsonContent;
                try
                {
                    jsonContent = await reader.ReadToEndAsync();
                }
                catch (OperationCanceledException)
                {
                    // 请求被取消，正常退出
                    return;
                }

                if (string.IsNullOrWhiteSpace(jsonContent))
                {
                    return;
                }

                var jsonObject = JsonConvert.DeserializeObject<JToken>(jsonContent);
                switch (jsonObject)
                {
                    case JArray jArray:
                        allParams["list"] = jsonContent.ToDictionary();
                        break;
                    case JObject jObject:
                        foreach (var property in jObject)
                        {
                            allParams[property.Key] = IsPasswordField(property.Key) ? "********" : property.Value;
                        }
                        break;
                }
            }
            finally
            {
                request.Body.Position = 0; // 重置流位置以便后续中间件读取
            }
        }

        private static bool IsJsonContentType(string contentType)
        {
            return !string.IsNullOrEmpty(contentType) && contentType.IndexOf("application/json", StringComparison.OrdinalIgnoreCase) >= 0;
        }

        private static bool IsPasswordField(string fieldName)
        {
            return fieldName.Equals("password", StringComparison.OrdinalIgnoreCase);
        }
    }
}
